package cn.donting.jme.editor.scene;

import cn.donting.jme.EditorContent;
import com.jme3.export.*;
import com.jme3.export.binary.BinaryExporter;
import com.jme3.export.binary.BinaryImporter;
import com.jme3.light.DirectionalLight;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
import com.jme3.scene.Node;
import lombok.Getter;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.IdentityHashMap;
import java.util.List;

@Getter
public class Scene implements Savable {
    public static final String extName = "scene";
    private Node rootNode;

    private ArrayList<SceneCamera> cameras = new ArrayList<>();

    private IdentityHashMap<Savable, ArrayList<Wrapper>> wrappers = new IdentityHashMap<>();


    @Override
    public void write(JmeExporter ex) throws IOException {
        OutputCapsule capsule = ex.getCapsule(this);
        capsule.write(rootNode, "rootNode", null);
        capsule.writeSavableArrayList(cameras, "cameras", null);
    }

    @Override
    public void read(JmeImporter im) throws IOException {
        InputCapsule capsule = im.getCapsule(this);
        rootNode = (Node) capsule.readSavable("rootNode", new Node());
        cameras = capsule.readSavableArrayList("cameras", new ArrayList<>());
    }

    public <T extends Wrapper> T getWrapper(Savable savable, Class<T> wrapperClass) {
        ArrayList<Wrapper> wrappers = this.wrappers.get(savable);
        if (wrappers == null) {
            wrappers = new ArrayList<>();
            this.wrappers.put(savable, wrappers);
        }
        for (Wrapper w : wrappers) {
            if (w.getClass().equals(wrapperClass)) {
                return (T) w;
            }
        }
        try {
            T t = wrapperClass.getConstructor().newInstance();
            t.initValue(savable);
            wrappers.add(t);
            return t;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }


    public static Scene newInstance() {
        Scene scene = new Scene();
        scene.rootNode = new Node("场景根节点");
        // #4 创建一束阳光，并让它斜向下照射，好使我们能够看清那个方块。
        DirectionalLight sun = new DirectionalLight();
        sun.setDirection(new Vector3f(-1, -2, -3));
        scene.rootNode.addLight(sun);
        SceneCamera sceneCamera = SceneCamera.newInstance("main", SceneCamera.CameraPos.Main, true);
        scene.getCameras().add(sceneCamera);
        return scene;
    }

}
